<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Excel预览 - SheetJS</title>
    <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
    <style>
        body {
            margin: 0;
            padding: 20px;
            font-family: Arial, sans-serif;
            background: #f5f5f5;
        }

        .container {
            padding: 20px;
            max-width: 1600px;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            min-height: calc(100vh - 80px);
            display: flex;
            flex-direction: column;
        }

        .file-input-wrapper {
            margin-bottom: 20px;
            padding: 15px;
            border: 2px dashed #ddd;
            border-radius: 8px;
            text-align: center;
            transition: all 0.3s;
        }

        .file-input-wrapper:hover {
            border-color: #409EFF;
            background: #f5f7fa;
        }

        #status {
            margin: 10px 0;
            padding: 10px;
            color: #666;
        }

        .sheet-tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
            border-bottom: 1px solid #ddd;
            padding: 10px;
            overflow-x: auto;
        }

        .sheet-tab {
            padding: 8px 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            background: white;
            transition: all 0.3s;
        }

        .sheet-tab:hover {
            border-color: #409EFF;
            color: #409EFF;
        }

        .sheet-tab.active {
            background: #409EFF;
            color: white;
            border-color: #409EFF;
        }

        #excel-container {
            flex: 1;
            overflow: auto;
            border: 1px solid #ddd;
            border-radius: 4px;
            position: relative;
        }

        .excel-table {
            width: auto;
            border-collapse: collapse;
            border-spacing: 0;
            table-layout: fixed;
            font-size: 12px;
        }

        .excel-table th,
        .excel-table td {
            border: 1px solid #e0e0e0;
            padding: 3px 6px;
            min-width: 30px;
            height: 18px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            box-sizing: border-box;
            position: relative;
            line-height: 1.2;
        }

        .excel-table th {
            padding: 4px 6px;
            height: 22px;
            background: #f5f7fa;
            font-weight: bold;
            text-align: center;
            position: sticky;
            top: 0;
            z-index: 1;
            font-size: 12px;
        }

        .excel-table tr:nth-child(even) {
            background: #fafafa;
        }

        .excel-table tr:hover {
            background: #f5f7fa;
        }

        .excel-table td.merged {
            background-color: inherit !important;
            border: none;
        }

        .excel-table td.hidden {
            display: none;
        }

        .excel-table td.number {
            text-align: right;
            font-family: Consolas, monospace;
            padding-right: 8px;
        }

        .excel-table td.date {
            text-align: center;
            min-width: 80px;
        }

        .excel-table td[title] {
            cursor: default;
        }

        .excel-table .col-auto {
            width: auto;
        }

        .excel-table td.editing {
            padding: 0 !important;
            position: relative;
        }

        .excel-table td.editing input {
            width: 100%;
            height: 100%;
            border: 2px solid #409EFF;
            padding: 2px 5px;
            outline: none;
            font-size: 12px;
            font-family: inherit;
            box-sizing: border-box;
        }

        .excel-table td.selected {
            background-color: #e6f3ff !important;
        }

        .toolbar {
            padding: 10px;
            border-bottom: 1px solid #ddd;
            display: flex;
            gap: 10px;
            align-items: center;
        }

        .toolbar button {
            padding: 6px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            cursor: pointer;
            transition: all 0.3s;
        }

        .toolbar button:hover {
            border-color: #409EFF;
            color: #409EFF;
        }

        .toolbar button.active {
            background: #409EFF;
            color: white;
            border-color: #409EFF;
        }

        .excel-container-wrapper {
            position: relative;
            overflow: auto;
            flex: 1;
        }

        .resize-handle {
            position: absolute;
            right: 0;
            top: 0;
            bottom: 0;
            width: 4px;
            background: transparent;
            cursor: col-resize;
        }

        .excel-table th {
            position: relative;
        }

        .excel-table th:hover .resize-handle {
            background: #409EFF;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="file-input-wrapper">
            <input type="file" id="fileInput" accept=".xlsx,.xls">
            <p style="margin: 10px 0 0; color: #909399;">支持.xlsx和.xls格式的Excel文件</p>
        </div>
        <div id="status"></div>
        <div id="sheet-tabs" class="sheet-tabs"></div>
        <div id="excel-container"></div>
        <div class="toolbar">
            <button id="editModeBtn">编辑模式</button>
            <button id="saveBtn" style="display:none;">保存</button>
            <button id="cancelBtn" style="display:none;">取消</button>
        </div>
    </div>

    <script>
        const status = document.getElementById('status');
        const container = document.getElementById('excel-container');
        const sheetTabs = document.getElementById('sheet-tabs');
        let workbook = null;
        let isEditMode = false;
        let currentEditCell = null;
        let originalData = null;

        function showStatus(message) {
            status.textContent = message;
            console.log(message);
        }

        // 应用单元格样式
        function applyCellStyle(cell, td) {
            if (!cell || !cell.s) return;

            // 字体样式
            if (cell.s.font) {
                if (cell.s.font.bold) td.style.fontWeight = 'bold';
                if (cell.s.font.italic) td.style.fontStyle = 'italic';
                if (cell.s.font.underline) td.style.textDecoration = 'underline';
                if (cell.s.font.name) td.style.fontFamily = cell.s.font.name;
                if (cell.s.font.sz) td.style.fontSize = `${cell.s.font.sz}pt`;
                if (cell.s.font.color) td.style.color = `#${cell.s.font.color.rgb}`;
            }

            // 背景色
            if (cell.s.fill && cell.s.fill.fgColor) {
                td.style.backgroundColor = `#${cell.s.fill.fgColor.rgb}`;
            }

            // 对齐方式
            if (cell.s.alignment) {
                td.style.textAlign = cell.s.alignment.horizontal || 'left';
                td.style.verticalAlign = cell.s.alignment.vertical || 'middle';
            }

            // 边框
            if (cell.s.border) {
                const borders = ['top', 'right', 'bottom', 'left'];
                borders.forEach(border => {
                    if (cell.s.border[border]) {
                        const style = cell.s.border[border].style;
                        const color = cell.s.border[border].color;
                        td.style[`border${border.charAt(0).toUpperCase() + border.slice(1)}`] =
                            `1px solid ${color ? '#' + color.rgb : '#000'}`;
                    }
                });
            }
        }

        // 显示工作表
        function showSheet(sheetName) {
            const worksheet = workbook.Sheets[sheetName];
            const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1');

            // 获取列宽信息
            const colWidths = new Map();

            // 从工作表中获取列宽信息
            if (worksheet['!cols']) {
                worksheet['!cols'].forEach((col, index) => {
                    if (col.wpx) {
                        colWidths.set(index, col.wpx + 'px');
                    }
                });
            }

            // 如果没有预设列宽，计算合适的列宽
            for (let C = range.s.c; C <= range.e.c; C++) {
                if (colWidths.has(C)) continue;

                let maxLength = XLSX.utils.encode_col(C).length;
                for (let R = range.s.r; R <= range.e.r; R++) {
                    const cell_address = XLSX.utils.encode_cell({ r: R, c: C });
                    const cell = worksheet[cell_address];
                    if (cell) {
                        const content = formatCellContent(cell);
                        maxLength = Math.max(maxLength, content.toString().length);
                    }
                }
                // 根据内容长度计算列宽（每个字符约8像素）
                colWidths.set(C, Math.min(Math.max(maxLength * 8, 40), 200) + 'px');
            }

            // 创建合并单元格映射
            const mergesMap = new Map();
            if (worksheet['!merges']) {
                worksheet['!merges'].forEach(merge => {
                    for (let R = merge.s.r; R <= merge.e.r; R++) {
                        for (let C = merge.s.c; C <= merge.e.c; C++) {
                            if (R !== merge.s.r || C !== merge.s.c) {
                                mergesMap.set(`${R},${C}`, {
                                    start: merge.s,
                                    isHidden: true
                                });
                            } else {
                                mergesMap.set(`${R},${C}`, {
                                    start: merge.s,
                                    rowSpan: merge.e.r - merge.s.r + 1,
                                    colSpan: merge.e.c - merge.s.c + 1
                                });
                            }
                        }
                    }
                });
            }

            let html = '<table class="excel-table">';

            // 添加列标题
            html += '<thead><tr><th style="background:#f5f7fa;width:35px;"></th>';
            for (let C = range.s.c; C <= range.e.c; C++) {
                const width = colWidths.get(C);
                html += `
                    <th style="background:#f5f7fa;width:${width}">
                        ${XLSX.utils.encode_col(C)}
                        <div class="resize-handle" data-col="${C}"></div>
                    </th>
                `;
            }
            html += '</tr></thead><tbody>';

            // 添加数据行
            for (let R = range.s.r; R <= range.e.r; R++) {
                html += `<tr><td style="background:#f5f7fa;text-align:center;min-width:35px;">${R + 1}</td>`;
                for (let C = range.s.c; C <= range.e.c; C++) {
                    const mergeInfo = mergesMap.get(`${R},${C}`);
                    if (mergeInfo?.isHidden) continue;

                    const cell_address = XLSX.utils.encode_cell({ r: R, c: C });
                    const cell = worksheet[cell_address];

                    let cellClass = 'col-auto';
                    let cellContent = '';
                    let title = '';

                    if (cell) {
                        if (cell.t === 'n') cellClass += ' number';
                        if (cell.t === 'd') cellClass += ' date';
                        cellContent = formatCellContent(cell);
                        // 添加工具提示
                        title = cellContent;
                    }

                    const attrs = [
                        `data-cell="${cell_address}"`,
                        `class="${cellClass}"`,
                        title ? `title="${title}"` : '',
                        'ondblclick="startEdit(this)"'
                    ];

                    if (mergeInfo) {
                        if (mergeInfo.rowSpan) attrs.push(`rowspan="${mergeInfo.rowSpan}"`);
                        if (mergeInfo.colSpan) attrs.push(`colspan="${mergeInfo.colSpan}"`);
                    }

                    html += `<td ${attrs.join(' ')}>${cellContent}</td>`;
                }
                html += '</tr>';
            }
            html += '</tbody></table>';

            container.innerHTML = html;

            // 应用样式
            const cells = container.querySelectorAll('td[data-cell]');
            cells.forEach(td => {
                const cellAddress = td.getAttribute('data-cell');
                const cell = worksheet[cellAddress];
                if (cell) {
                    applyCellStyle(cell, td);
                }
            });

            // 添加拖动调整列宽功能
            function initializeResizeHandles() {
                const handles = document.querySelectorAll('.resize-handle');
                handles.forEach(handle => {
                    handle.addEventListener('mousedown', startResize);
                });
            }

            function startResize(e) {
                const handle = e.target;
                const th = handle.parentElement;
                const startX = e.pageX;
                const startWidth = th.offsetWidth;

                function onMouseMove(e) {
                    const width = startWidth + (e.pageX - startX);
                    th.style.width = Math.max(40, Math.min(400, width)) + 'px';
                }

                function onMouseUp() {
                    document.removeEventListener('mousemove', onMouseMove);
                    document.removeEventListener('mouseup', onMouseUp);
                }

                document.addEventListener('mousemove', onMouseMove);
                document.addEventListener('mouseup', onMouseUp);
            }

            // 在表格渲染完成后初始化拖动功能
            setTimeout(initializeResizeHandles, 0);
        }

        // 添加格式化单元格内容函数
        function formatCellContent(cell) {
            if (!cell) return '';

            if (cell.t === 'n') {
                // 数字格式化
                if (cell.z) {
                    // 处理百分比
                    if (cell.z.includes('%')) {
                        return (cell.v * 100).toFixed(2) + '%';
                    }
                    // 处理小数
                    if (cell.z.includes('.00')) {
                        return cell.v.toFixed(2);
                    }
                }
                // 处理整数
                return cell.v.toString();
            }

            if (cell.t === 'd') {
                // 日期格式化
                return cell.v.toLocaleDateString();
            }

            // 其他类型直接返回格式化后的值
            return XLSX.utils.format_cell(cell);
        }

        // 更新工作表标签
        function updateSheetTabs() {
            sheetTabs.innerHTML = '';
            workbook.SheetNames.forEach((name, index) => {
                const tab = document.createElement('button');
                tab.className = 'sheet-tab' + (index === 0 ? ' active' : '');
                tab.textContent = name;
                tab.onclick = () => {
                    document.querySelectorAll('.sheet-tab').forEach(t => t.classList.remove('active'));
                    tab.classList.add('active');
                    showSheet(name);
                };
                sheetTabs.appendChild(tab);
            });
        }

        // 文件上传处理
        document.getElementById('fileInput').addEventListener('change', async function (e) {
            try {
                const file = e.target.files[0];
                if (!file) {
                    showStatus('没有选择文件');
                    return;
                }

                showStatus('正在读取文件...');
                const arrayBuffer = await file.arrayBuffer();

                showStatus('正在解析Excel...');
                workbook = XLSX.read(arrayBuffer, {
                    type: 'array',
                    cellStyles: true,
                    cellNF: true,
                    cellDates: true
                });

                updateSheetTabs();
                showSheet(workbook.SheetNames[0]);
                showStatus('加载完成');

            } catch (error) {
                console.error('Error:', error);
                showStatus('发生错误: ' + error.message);
            }
        });

        // 添加编辑相关函数
        function startEdit(td) {
            if (!isEditMode) return;

            // 如果已经在编辑其他单元格，先保存它
            if (currentEditCell) {
                saveEdit();
            }

            try {
                const cellAddress = td.getAttribute('data-cell');
                const activeSheet = sheetTabs.querySelector('.active').textContent;
                const worksheet = workbook.Sheets[activeSheet];

                if (!worksheet) {
                    console.error('找不到工作表:', activeSheet);
                    return;
                }

                const cell = worksheet[cellAddress];
                const value = cell ? formatCellContent(cell) : '';

                td.classList.add('editing');
                // 转义特殊字符，防止 HTML 注入
                const escapedValue = value.replace(/"/g, '&quot;');
                td.innerHTML = `<input type="text" value="${escapedValue}" onblur="saveEdit()" onkeydown="handleEditKeydown(event)">`;
                currentEditCell = td;
                td.querySelector('input').focus();
            } catch (error) {
                console.error('编辑单元格时出错:', error);
                showStatus('编辑单元格时出错: ' + error.message);
            }
        }

        function saveEdit() {
            if (!currentEditCell) return;

            try {
                const input = currentEditCell.querySelector('input');
                if (!input) return;

                const cellAddress = currentEditCell.getAttribute('data-cell');
                const activeSheet = sheetTabs.querySelector('.active').textContent;
                const worksheet = workbook.Sheets[activeSheet];

                if (!worksheet) {
                    throw new Error('找不到工作表');
                }

                // 更新单元格值
                worksheet[cellAddress] = {
                    t: 's',  // 设置为字符串类型
                    v: input.value
                };

                // 更新显示
                currentEditCell.classList.remove('editing');
                currentEditCell.innerHTML = input.value;
                currentEditCell = null;
            } catch (error) {
                console.error('保存编辑时出错:', error);
                showStatus('保存编辑时出错: ' + error.message);
                // 恢复原始显示
                cancelEdit();
            }
        }

        function handleEditKeydown(event) {
            if (event.key === 'Enter') {
                saveEdit();
            } else if (event.key === 'Escape') {
                cancelEdit();
            }
        }

        function cancelEdit() {
            if (!currentEditCell) return;
            try {
                const activeSheet = sheetTabs.querySelector('.active').textContent;
                showSheet(activeSheet);
                currentEditCell = null;
            } catch (error) {
                console.error('取消编辑时出错:', error);
                showStatus('取消编辑时出错: ' + error.message);
            }
        }

        // 添加工具栏按钮事件
        document.getElementById('editModeBtn').addEventListener('click', function () {
            isEditMode = !isEditMode;
            this.classList.toggle('active');
            document.getElementById('saveBtn').style.display = isEditMode ? 'block' : 'none';
            document.getElementById('cancelBtn').style.display = isEditMode ? 'block' : 'none';

            if (isEditMode) {
                // 保存原始数据
                originalData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
            } else {
                cancelEdit();
            }
        });

        document.getElementById('saveBtn').addEventListener('click', function () {
            if (currentEditCell) {
                saveEdit();
            }
            // 这里可以添加保存到文件的功能
            const newFile = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
            const blob = new Blob([newFile], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'edited_excel.xlsx';
            a.click();
            URL.revokeObjectURL(url);
        });

        document.getElementById('cancelBtn').addEventListener('click', function () {
            if (originalData) {
                workbook = XLSX.read(originalData, {
                    type: 'array',
                    cellStyles: true,
                    cellNF: true,
                    cellDates: true
                });
                showSheet(workbook.SheetNames[0]);
            }
            isEditMode = false;
            document.getElementById('editModeBtn').classList.remove('active');
            document.getElementById('saveBtn').style.display = 'none';
            document.getElementById('cancelBtn').style.display = 'none';
        });
    </script>
</body>

</html>